﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Entidades;
using RandomKeyGenerator;
using Support;
using Entidades.entidades;
using System.Collections.Generic;
using AlgoritmoConstrutivo;

namespace UnitTestAlgoritmoConstrutivo
{
    [TestClass]
    public class BRKGATest
    {
        private BRKGA framework;

        private const int INDIVIDUOS = 100;
        private Cromossomo[] cromossomos; //vetor de vetores de numeros aleatorios
        private FabricaCromossomos fabricaRandomKeys; //fabrica de numeros aleatorios
        private int numeroNos = 10;


        [TestMethod]
        public void BRKGAEstáGerandoOsElitesEOsMutantesCorretamente()
        {
            this.fabricaRandomKeys = new FabricaCromossomos(this.numeroNos);
            this.cromossomos = new Cromossomo[INDIVIDUOS];

            this.GeraCromossomos();

            this.configFramework();

            List<GrafoResumido> grList = this.MontaGrafoResumido();
            grList.Sort();


            this.framework =  new BRKGA(this.cromossomos, grList, 10);

            Cromossomo[] novaPopulacao = this.framework.GenerateNewPopulation();


            //for (int i = 0; i < Configuration.PopulationElite; i++)
            //{
            //    Assert.IsTrue(cromossomos[i] != null); //verifico se algum individuo não foi gerado.

            //    Assert.IsTrue(this.VerificarTodosOsIndicesGerados(this.cromossomos[i])); //verifico se todos os genes foram gerados.

            //    for (int k = 0; k < this.numeroNos; k++)
            //    {
            //        Assert.AreEqual(this.cromossomos[grList[i].Individuo].Chaves[k], novaPopulacao[i].Chaves[k]); //verifico se os X elites foram corretamente copiados.

            //    }
            //}

            
            ////para os mutantes vamos verificar se eles estão comtemplando todos os nós.
            //int numMutantes = (int) Configuration.PopulationMutant;
            //--numMutantes;

            //for (int i = numMutantes; i >= (this.cromossomos.Length - Configuration.PopulationMutant); i--)
            //{
            //    Assert.IsTrue(cromossomos[i] != null); //verifico se algum individuo não foi gerado.
            //    Assert.IsTrue(this.VerificarTodosOsIndicesGerados(this.cromossomos[i])); //verifico se todos os genes dos individuos mutantes foram gerados.
            //}

        }

        private void configFramework()
        {
            //Entidades.Configuration.Population = 100;
            //Entidades.Configuration.EliteProb = 0.15;
            //Entidades.Configuration.MutantProb = 0.10;
            //Entidades.Configuration.PopulationInheritanceProbability = 0.7;

            //Entidades.Configuration.MIN_CLUSTERS = 0.2;
            //Entidades.Configuration.MAX_CLUSTERS = 0.4;
            //Entidades.Configuration.NUM_VIZINHOS = 3;
            //Entidades.Configuration.LIMITE_BUSCA_NOS = 0.3;


            //Entidades.Configuration.PopulationElite = Entidades.Configuration.EliteProb * Entidades.Configuration.Population;
            //Entidades.Configuration.PopulationMutant = (int) Entidades.Configuration.MutantProb * Entidades.Configuration.Population;
            //Entidades.Configuration.ManterGene = -1;
        }

        private List<GrafoResumido> MontaGrafoResumido()
        {

            List<GrafoResumido> grList = new List<GrafoResumido>();


            for (int i = 0; i < INDIVIDUOS; i++)
            {

                GrafoResumido gr = new GrafoResumido(this.fabricaRandomKeys.GenerateRandomDoubleNumberFromInterval(0,5), i);
                grList.Add(gr);
            }

            return grList;
        }

        /// <summary>
        /// A partir do numero de cromossomos definido, gera cada um dos cromossomos.
        /// </summary>
        private void GeraCromossomos()
        {
            for (int i = 0; i < INDIVIDUOS; i++)
            {
                this.cromossomos[i] = new Cromossomo();
                this.cromossomos[i].Chaves = this.fabricaRandomKeys.GenerateRandomKeys();
            }
        }

        private bool VerificarTodosOsIndicesGerados(Cromossomo cromossomos)
        {
            int numNos = this.numeroNos;

            for (int k = 0; k < numNos; k++)
            {

                Gene a = Array.Find(cromossomos.Chaves, element => element.Indice == k);

                if (a == null)
                    return false;
            }

            return true;
        }


        
    }
}
